package cfca.seal.web.action.maintain;

import cfca.seal.common.MyDataSource;
import cfca.seal.exception.CodeException;
import cfca.seal.system.Env;
import cfca.seal.util.FileUtil;
import cfca.seal.web.service.SealService;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.sql.DataSource;
import org.apache.commons.dbcp.BasicDataSource;
import org.apache.commons.fileupload.FileItem;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.commons.CommonsMultipartFile;

@Controller
@RequestMapping({"/revertSeal"})
public class RevertSealAction
{
  private static final Logger log = LoggerFactory.getLogger("web_sys");

  @Resource
  private SealService sealService;

  @Resource
  DataSource dataSource;

  @RequestMapping({"/v_list"})
  public String viewList(HttpServletRequest request, ModelMap modelMap)
    throws CodeException
  {
    return "sys/revert/input.html";
  }

  @RequestMapping(value={"/o_revert_seal"}, method={org.springframework.web.bind.annotation.RequestMethod.POST})
  public String submitSealConfigRecovery(@RequestParam("zipFile") CommonsMultipartFile zipFile, ModelMap modelMap, HttpServletRequest request)
    throws CodeException
  {
    if (zipFile.isEmpty()) {
      modelMap.put("zipFileError", "请加入备份文件。");
      return "sys/revert/input.html";
    }if (!zipFile.getFileItem().getName().toLowerCase().endsWith(".zip")) {
      modelMap.put("zipFileError", "备份文件后缀必须是zip格式。");
      return "sys/revert/input.html";
    }

    log.info("电子印章配置恢复开始");
    log.info("电子印章配置恢复的文件名: " + zipFile.getFileItem().getName());
    try {
      sealUpdate(zipFile.getInputStream());
    }
    catch (Exception e) {
      log.error("电子印章配置恢复失败", e);
      throw new CodeException("C0001", "系统恢复失败", e);
    }
    log.info("电子印章配置恢复成功");
    String resultInfo = "电子印章配置恢复成功";
    modelMap.put("resultInfo", resultInfo);
    return "sys/revert/input.html";
  }

  private void sealUpdate(InputStream fis)
    throws Exception
  {
    log.info("电子印章配置恢复");
    String dbfill = getClass().getClassLoader().getResource("sqlite.db").getPath();
    ((BasicDataSource)this.dataSource).close();
    FileUtil.deleteDirectory(Env.configDir + File.separator + "cert");
    FileUtil.deleteDirectory(Env.configDir + File.separator + "crl");
    ZipInputStream zipFile = new ZipInputStream(fis);
    ZipEntry zipEntry = null;
    BufferedOutputStream os = null;
    try {
      while ((zipEntry = zipFile.getNextEntry()) != null) {
        File file = null;
        String fileName = zipEntry.getName();
        log.info("电子印章配置恢复的压缩文件名:" + fileName);
        if (fileName.equals("sqlite.db")) {
          file = new File(dbfill);
          file.createNewFile();
          os = new BufferedOutputStream(new FileOutputStream(file));
          int b;
          while ((b = zipFile.read()) != -1) {
            os.write(b);
          }
          os.close();
        } else {
          file = new File(Env.configDir + File.separator + fileName);
          File fileTmp = file.getParentFile();
          if (!fileTmp.exists()) {
            fileTmp.mkdirs();
          }
          if (zipEntry.isDirectory()) {
            file.mkdirs();
          }
          else {
            file.createNewFile();
            os = new BufferedOutputStream(new FileOutputStream(file));
            int b;
            while ((b = zipFile.read()) != -1) {
              os.write(b);
            }
            os.close();
          }
        }
      }
    } catch (IOException e) {
      log.error("IO读写失败，系统升级失败", e);
      throw new CodeException("C0001", "IO读写错误,系统升级失败", e);
    } catch (Exception e) {
      log.error("系统升级失败", e);
      throw new CodeException("C0001", "系统升级失败", e);
    } finally {
      if (os != null) {
        os.flush();
        os.close();
      }
      zipFile.close();
      fis.close();
      ((MyDataSource)this.dataSource).open();
    }
  }
}